/*
*********************************************************************************************************
*
*    模块名称 : 编程器接口
*    文件名称 : prog_if.h
*    版    本 : V1.0
*    说    明 : 头文件
*
*    Copyright (C), 2014-2015, 安富莱电子 www.armfly.com
*
*********************************************************************************************************
*/

#ifndef __PROG_IF_H_
#define __PROG_IF_H_
#include "stm32f4xx.h"
#include "UID_Encryption.h"

/* */
typedef enum
{
    CHIP_SWD_ARM     = 0,
    CHIP_SWIM_STM8   = 1,
    CHIP_SPI_FLASH   = 2,
    CHIP_I2C_EEPROM  = 3,
    CHIP_NUVOTON_8051  = 4,   /* 新唐51系,如 N76E类型 */
}CHIP_TYPE_E;

/* 校验模式 */
typedef enum
{
    VERIFY_AUTO = 0,            /* 自动选择. FLM中有CRC就执行, 没有就采用ReadBack  */
    VERIFY_READ_BACK  = 1,      /* 读回校验 */
    VERIFY_SOFT_CRC   = 2,      /* 软件CRC */
    VERIFY_STM32_CRC  = 3,      /* STM32 CRC硬件算法 */
}VERIFY_MODE_E;

/* 数据类型 */
typedef enum
{
    INVALID_DATA = 0,     //无效的
    FILE_DATA  = 1,       //文件数据
		SN_DATA = 2,           //滚码数据
	  CONST_DATA = 3,        //常量
	  RANDOM_DATA = 4,
		UIDKEY_DATA = 5
}DATA_TYPE_E;

/* 复位方式 */
typedef enum
{
	  AUTO_RESET = 0,       //自动复位
  	SOFT_RESET  = 1,      //软件复位
	  HARD_RESET = 2        //硬件复位
}RESET_TYPE_E;


typedef struct 
{
    char FilePath[128];         /* lua文件路径 */    
    
    CHIP_TYPE_E ChipType;       /* 芯片类型 */
    
    uint32_t Time;
    
    float Percent;              /* 烧录进度 */
    
    uint8_t Err;
    
    uint32_t FLMFuncTimeout;    /* 执行算法函数超时时间。擦除整片时可能耗时20秒 */
    uint8_t FLMFuncDispProgress;/* 临时处理，正在擦除全片， 需要显示进度 */
    uint32_t FLMFuncDispAddr;   /* 进度条中的地址栏 */
    
    uint8_t AutoStart;      /* 检测到芯片后自动开始编程 */
    
    int32_t NowProgCount;   /* 编程次数。掉电清零 */
    
    uint32_t VerifyMode;    /* 校验模式 */
    uint32_t EraseChipTime; /* 全片擦除时间 */
    
    uint8_t VerifyOptionByteDisalbe;   /* 1 表示芯片设置读保护时,不校验 (STM32F207VC设置读保护后会即可生效导致无法校验) */
    
    uint32_t SwdClockDelay;     /* SWD时钟延迟，0表示最快，值越大速度越慢 */
    
    uint32_t SwdResetDelay;     /* 硬件复位后的延迟时间，ms */
    uint32_t ResetMode;         /* 复位模式 */
    
    uint8_t AbortOnError;       /* 多路模式，0表示出错时继续烧录OK的芯片  1表示出错后立刻同时终止 */
    
    uint8_t ChNum;                  /* 通道个数 */
    
    uint16_t MulDelayUsReadData;    /* 多路模式读内存操作中的延迟，仅 MM32L073系列 */    
}OFFLINE_PROG_T;


typedef struct
{
   	uint8_t Type;		        	/* 数据类型，表示是文件还是用户数据 */
    uint32_t StartAddr;       /* 起始地址 */   
    uint32_t EndAddr;         /* 结束地址 */
	  char *Path;               /* 文件路径 */
  	uint8_t *Data;               /* 指向数据缓冲区 */
	  uint32_t Len;             /* 数据长度 */
}FILE_CELL_T;

#define MAX_FIX_LINE    128
#define MAX_FILE_LINE   10


typedef struct
{
    uint32_t Count;          /* 文件个数 */
    FILE_CELL_T Lines[MAX_FIX_LINE];
}PROG_DATA_T;

typedef struct
{
	uint32_t Enable;
	uint32_t Step;
	uint32_t Format;
	uint32_t InitValue;
	uint32_t Len;
	uint32_t StartAddr;
}SN_CONFIG_T;

typedef struct
{
	uint32_t Enable;
	uint32_t StartAddr;
	uint32_t Len;
	uint8_t  *Data;
}CONST_CONFIG_T;

typedef struct
{
	uint32_t Count;           /* 有效数据个数 */
	CONST_CONFIG_T Lines[MAX_FIX_LINE];
}CONST_CELL_T;

typedef struct
{
  uint32_t Enable;
	uint32_t Len;
	uint32_t StartAddr;
}RANDOM_CONFIG_T;

typedef struct
{
	uint32_t Count;           /* 有效数据个数 */
	RANDOM_CONFIG_T Lines[MAX_FIX_LINE];
}RANDOM_CELL_T;

typedef struct
{
  uint32_t Enable;
	uint32_t StartAddr;
	uint32_t Len;
	uint32_t Format;
	uint32_t Algorithm;
	uint8_t  UserID[12];
	uint8_t  UIDKey[12];
}UID_ENCRYPT_T;

typedef struct
{
  uint32_t UIDCheckEnable;
	uint32_t CountCheckEnable;
	uint32_t ProgCount;
	uint8_t  StartUID[12];
	uint8_t  EndID[12];
}CHECK_VALID_T;

typedef struct
{	
	uint32_t UIDAddr;             /*芯片UID起始地址*/
	uint32_t OB_WRPByte;          /*要检查选项字节的个数*/
	uint32_t OB_WriteByte;				/*写入选项字节的字节个数*/
	uint8_t  ChipUID[12];         /*芯片UID*/
	uint8_t  *OB_SecureOn;        /*解除保护时写入的值*/
	uint8_t  *OB_SecureOff;       /*加密时选择的值*/
	uint8_t  *OB_WRP_Mask;        /*选项字节掩码*/
	uint8_t  *OB_WRP_Value;       /*芯片没有读写保护的选项字节的值*/
	uint32_t *OB_WriteAddr;       /*写入选项字节时的地址*/
  uint32_t *OB_WRP_Addr;        /*判断有无读写保护时选项字节的地址*/
}CHIP_INFO_T;
typedef struct
{
		char *AlgoFile_FLASH;
	  char *AlgoFile_OTP;
		char *AlgoFile_OPT;
	  uint32_t SwdClockDelay;       /*SWD时钟频率*/
  	uint32_t SwdResetDelay;       /*复位后延时*/
  	uint32_t EnableOB;            /*写选项字节*/
		uint32_t VerifyMode;          /*校验模式 */
  	uint32_t CompleteReset;       /*编程结束后复位*/
		uint32_t ResetMode;           /*复位模式 */
	  uint32_t EraseChip;           /*是否全片擦除 0表示按扇区擦除，1表示全片擦除，其他值不擦除*/
		uint32_t ContinuProg;         /*是否连续烧录*/
		uint32_t CheckProtect;        /*是否检查读保护*/
		CHECK_VALID_T CheckValid;     /*编程次数 ，UID范围检查*/
		CHIP_INFO_T   ChipInfo;       /*芯片信息*/
		UID_ENCRYPT_T UIDEncrypt;     /*UID加密配置*/
  	RANDOM_CELL_T RandomConfig;   /*随机数配置*/
		CONST_CELL_T ProgConst;       /*用户自定义数据*/
		SN_CONFIG_T SNConfig;         /*滚码配置*/
    PROG_DATA_T ProgData;         /*编程要写入的数据*/
}PROG_CONFIG_T;

extern OFFLINE_PROG_T g_tProg;


void PG_ReloadLuaVar(void);

uint8_t WaitChipInsert(void);
uint8_t WaitChipRemove(void);

uint8_t ProgCancelKey(void);
void PG_PrintText(char *_str);
void PG_PrintPercent(float _Percent, uint32_t _Addr);


uint16_t PG_SWD_InitProg(PROG_CONFIG_T *ProgConfig);
uint16_t PG_SWD_ProgFile(char *_Path, uint32_t _FlashAddr, uint32_t _EndAddr, uint32_t _CtrlByte,uint8_t *EraseSectorsFlag);
uint16_t PG_SWD_ProgBuf(PROG_CONFIG_T *ProgConfig,uint32_t _FlashAddr, uint8_t *_DataBuf, uint32_t _BufLen, uint8_t _Mode);
uint16_t PG_SWD_CheckAddr(PROG_CONFIG_T *ProgConfig);
uint16_t PG_SWD_ProgBuf_OB(PROG_CONFIG_T *ProgConfig,uint32_t _FlashAddr, uint8_t *_DataBuf, uint32_t _BufLen);
uint8_t PG_SWD_StartProg(PROG_CONFIG_T *ProgConfig);
uint16_t PG_SWD_EraseChip(PROG_CONFIG_T *ProgConfig,uint32_t _FlashAddr);
uint16_t PG_SWD_EraseSector(uint8_t *EraseSectorsFlag);

void DispProgProgress(char *_str, float _progress, uint32_t _addr);
//uint32_t GetChipTypeFromLua(lua_State *L);

uint32_t PG_GetPageSize(const char *_Algo);
uint32_t PG_GetDeviceAddr(const char *_Algo);
uint32_t PG_GetDeviceSize(const char *_Algo);
uint32_t PG_GetSectorSize(const char *_Algo, uint32_t _Addr);
uint8_t PG_CheckBlank(const char *_Algo, uint32_t _Addr, uint32_t _Size);
uint8_t PG_EraseSector(const char *_Algo, uint32_t _Addr);
uint8_t PG_EraseChip(void);
uint8_t PG_ProgramBuf(const char *_Algo, uint32_t _FlashAddr, uint8_t *_Buff, uint32_t _Size);
uint8_t PG_ReadBuf(const char *_Algo, uint32_t _FlashAddr, uint8_t *_Buff, uint32_t _Size);
uint8_t PG_SWD_ProgWork(void);
uint8_t PG_SWD_ContinuProg(PROG_CONFIG_T *ProgConfig);
extern uint8_t flash_buff[16*1024];   /* flash_buff[sizeof(FsReadBuf)]; */

#endif
